<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Basic Revisited
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora106.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora108.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Basic Revisited</H2>
<A NAME="sec-basic-rev"></A>
We now want to use <TT>ocamllex</TT> and <TT>ocamlyacc</TT> to replace 
function <TT>parse</TT> on page
<A HREF="book-ora058.html#fun-basic-parse">??</A> for Basic by some functions generated
from files specifying the lexicon and syntax of the language.<BR>
<BR>
To do this, we may not re-use as-is the type of lexical units that we
have defined. We will be forced to define a more precise type which
permits us to distinguish between operators, commands and keywords.<BR>
<BR>
We will also need to isolate the type declarations describing abstract
syntax within a file <TT>basic_types.mli</TT>. This will contain the
declaration of type <TT>sentences</TT> and all types needed by it.<BR>
<BR>
<A NAME="toc142"></A>
<H3> File <TT>basic_parser.mly</TT></H3><A NAME="basic-mly"></A>
<H5> Header</H5> The file header imports the types needed for the
abstract syntax as well as two auxiliary functions to convert from
character strings to their equivalent in the abstract syntax.


<PRE><BR><CODE>%{</CODE><BR><B>open</B><CODE> </CODE>Basic_types<CODE> </CODE>;;<BR><BR><B>let</B><CODE> </CODE>phrase_of_cmd<CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><B>match</B><CODE> </CODE>c<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>"RUN"</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Run<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"LIST"</CODE><CODE> </CODE>-&gt;<CODE> </CODE>List<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"END"</CODE><CODE> </CODE>-&gt;<CODE> </CODE>End<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE>"line : unexpected command"</CODE><BR>;;<BR><BR><B>let</B><CODE> </CODE>bin_op_of_rel<CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><B>match</B><CODE> </CODE>r<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>"="</CODE><CODE> </CODE>-&gt;<CODE> </CODE>EQUAL<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"&lt;"</CODE><CODE> </CODE>-&gt;<CODE> </CODE>INF<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"&lt;="</CODE><CODE> </CODE>-&gt;<CODE> </CODE>INFEQ<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"&gt;"</CODE><CODE> </CODE>-&gt;<CODE> </CODE>SUP<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"&gt;="</CODE><CODE> </CODE>-&gt;<CODE> </CODE>SUPEQ<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"&lt;&gt;"</CODE><CODE> </CODE>-&gt;<CODE> </CODE>DIFF<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE>"line : unexpected relation symbol"</CODE><BR>;;<BR><BR><CODE>%}</CODE><BR>

</PRE>
<BR>
<BR>

<H5> Declarations</H5> contains three sections: lexeme declarations,
their rule associativity and precedence declarations, and the 
declaration of the start symbol <TT>line</TT> which stands for the
parsing of a command or program line.<BR>
<BR>
<P>Lexical units are the following:


<PRE><BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE><CODE>&lt;</CODE>int<CODE>&gt;</CODE><CODE> </CODE>Lint<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE><CODE>&lt;</CODE>string<CODE>&gt;</CODE><CODE> </CODE>Lident<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE><CODE>&lt;</CODE>string<CODE>&gt;</CODE><CODE> </CODE>Lstring<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE><CODE>&lt;</CODE>string<CODE>&gt;</CODE><CODE> </CODE>Lcmd<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE>Lplus<CODE> </CODE>Lminus<CODE> </CODE>Lmult<CODE> </CODE>Ldiv<CODE> </CODE>Lmod<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE><CODE>&lt;</CODE>string<CODE>&gt;</CODE><CODE> </CODE>Lrel<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE>Land<CODE> </CODE>Lor<CODE> </CODE>Lneg<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE>Lpar<CODE> </CODE>Rpar<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE><CODE>&lt;</CODE>string<CODE>&gt;</CODE><CODE> </CODE>Lrem<CODE> </CODE><BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE>Lrem<CODE> </CODE>Llet<CODE> </CODE>Lprint<CODE> </CODE>Linput<CODE> </CODE>Lif<CODE> </CODE>Lthen<CODE> </CODE>Lgoto<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE>Lequal<BR><CODE> </CODE><CODE>%</CODE>token<CODE> </CODE>Leol<BR>

</PRE>

Their names are self-explanatory and they are described in file
<TT>basic_lexer.mll</TT> (see page <A HREF="book-ora107.html#basic-lex">??</A>).<BR>
<BR>
<P>Precedence rules between operators once again take the values assigned by
functions <TT>priority_uop</TT> and <TT>priority_binop</TT> defined
when first giving the grammar for our Basic (see page
<A HREF="book-ora058.html#subsec-gram-basic">??</A>). 


<PRE><BR><CODE> </CODE><CODE>%</CODE>right<CODE> </CODE>Lneg<BR><CODE> </CODE><CODE>%</CODE>left<CODE> </CODE>Land<CODE> </CODE>Lor<BR><CODE> </CODE><CODE>%</CODE>left<CODE> </CODE>Lequal<CODE> </CODE>Lrel<BR><CODE> </CODE><CODE>%</CODE>left<CODE> </CODE>Lmod<BR><CODE> </CODE><CODE>%</CODE>left<CODE> </CODE>Lplus<CODE> </CODE>Lminus<BR><CODE> </CODE><CODE>%</CODE>left<CODE> </CODE>Lmult<CODE> </CODE>Ldiv<BR><CODE> </CODE><CODE>%</CODE>nonassoc<CODE> </CODE>Lop<BR>

</PRE>

Symbol <TT>Lop</TT> will be used to process unary minus. It is not a
terminal in the grammar, but a ``pseudo non-terminal'' which allows
overloading of operators when two uses of an operator should not receive
the same precedence depending on context. This is the case with the
minus symbol (<TT>-</TT>). We will reconsider this point once we have
specified the rules in the grammar.<BR>
<BR>
<P>Since the start symbol is <TT>line</TT>, the function generated will
return the syntax tree for the parsed line.
<PRE>
 %start line
 %type &lt;Basic_types.phrase&gt; line
</PRE>
<H5> Grammar rules</H5> are decomposed into three non-terminals:
 <TT>line</TT> for a line; <TT>inst</TT> for an instruction in the language;
<TT>exp</TT> for expressions. The action associated with each rule simply
builds the corresponding abstract syntax tree.


<PRE><BR><CODE> </CODE><CODE>%%</CODE><BR>line<CODE> </CODE><CODE>:</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Lint<CODE> </CODE>inst<CODE> </CODE>Leol<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Line<CODE> </CODE>{num<CODE>=$</CODE><CODE>1</CODE>;<CODE> </CODE>inst<CODE>=$</CODE><CODE>2</CODE>}<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Lcmd<CODE> </CODE>Leol<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>phrase_of_cmd<CODE> </CODE><CODE>$</CODE><CODE>1</CODE><CODE> </CODE>}<BR><CODE> </CODE>;<BR><BR>inst<CODE> </CODE><CODE>:</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Lrem<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Rem<CODE> </CODE><CODE>$</CODE><CODE>1</CODE><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Lgoto<CODE> </CODE>Lint<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Goto<CODE> </CODE><CODE>$</CODE><CODE>2</CODE><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Lprint<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Print<CODE> </CODE><CODE>$</CODE><CODE>2</CODE><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Linput<CODE> </CODE>Lident<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Input<CODE> </CODE><CODE>$</CODE><CODE>2</CODE><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Lif<CODE> </CODE>exp<CODE> </CODE>Lthen<CODE> </CODE>Lint<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>If<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>2</CODE><CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Llet<CODE> </CODE>Lident<CODE> </CODE>Lequal<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Let<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>2</CODE><CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE>;<BR><BR>exp<CODE> </CODE><CODE>:</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Lint<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpInt<CODE> </CODE><CODE>$</CODE><CODE>1</CODE><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Lident<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpVar<CODE> </CODE><CODE>$</CODE><CODE>1</CODE><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Lstring<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpStr<CODE> </CODE><CODE>$</CODE><CODE>1</CODE><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Lneg<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpUnr<CODE> </CODE><TT>(</TT>NOT<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>exp<CODE> </CODE>Lplus<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpBin<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>PLUS<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>exp<CODE> </CODE>Lminus<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpBin<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>MINUS<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>exp<CODE> </CODE>Lmult<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpBin<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>MULT<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>exp<CODE> </CODE>Ldiv<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpBin<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>DIV<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>exp<CODE> </CODE>Lmod<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpBin<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>MOD<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>exp<CODE> </CODE>Lequal<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpBin<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>EQUAL<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>exp<CODE> </CODE>Lrel<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpBin<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE><TT>(</TT>bin_op_of_rel<CODE> </CODE><CODE>$</CODE><CODE>2</CODE><TT>)</TT><CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>exp<CODE> </CODE>Land<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpBin<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>AND<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>exp<CODE> </CODE>Lor<CODE> </CODE>exp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpBin<CODE> </CODE><TT>(</TT><CODE>$</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>OR<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Lminus<CODE> </CODE>exp<CODE> </CODE><CODE>%</CODE>prec<CODE> </CODE>Lop<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>ExpUnr<TT>(</TT>OPPOSITE<CODE>,</CODE><CODE> </CODE><CODE>$</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Lpar<CODE> </CODE>exp<CODE> </CODE>Rpar<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE><CODE>$</CODE><CODE>2</CODE><CODE> </CODE>}<BR><CODE> </CODE>;<BR><CODE> </CODE><CODE>%%</CODE><BR>

</PRE>

These rules do not call for particular remarks except: 
<PRE>
exp :
 ...
 | Lminus exp %prec Lop { ExpUnr(OPPOSITE, $2) }
</PRE>It concerns the use of unary <TT>-</TT>.
Keyword <CODE>%prec</CODE> that we find in it declares that this rule should receive
the precedence of <TT>Lop</TT> (here the highest precedence).<BR>
<BR>
<A NAME="toc143"></A>
<H3> File <TT>basic_lexer.mll</TT></H3><A NAME="basic-lex"></A>
Lexical analysis only contains one rule, <TT>lexer</TT>, which corresponds
closely to the old function <TT>lexer</TT> (see page
<A HREF="book-ora058.html#fun-lexer">??</A>). The semantic action associated with the
recognition of each lexical unit is simply the emission of the
related constructor. As the type of lexical units is declared in the
syntax rule file, we have to include the file here. We add a simple
auxiliary function that strips double quotation marks from 
character strings.


<PRE><BR>{<BR><CODE> </CODE><B>open</B><CODE> </CODE>Basic_parser<CODE> </CODE>;;<BR><BR><CODE> </CODE><B>let</B><CODE> </CODE>string_chars<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE>String.sub<CODE> </CODE>s<CODE> </CODE><CODE>1</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>String.length<CODE> </CODE>s<TT>)</TT><CODE>-</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>;;<BR>}<BR><BR>rule<CODE> </CODE>lexer<CODE> </CODE><CODE>=</CODE><CODE> </CODE>parse<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE><CODE>' '</CODE><CODE> </CODE><CODE>'\t'</CODE><CODE>]</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>lexer<CODE> </CODE>lexbuf<CODE> </CODE>}<BR><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'\n'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Leol<CODE> </CODE>}<BR><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'!'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lneg<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'&amp;'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Land<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'|'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lor<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'='</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lequal<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'%'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lmod<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'+'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lplus<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'-'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lminus<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'*'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lmult<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'/'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Ldiv<CODE> </CODE>}<BR><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[</CODE><CODE>'&lt;'</CODE><CODE> </CODE><CODE>'&gt;'</CODE><CODE>]</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lrel<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"&lt;="</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lrel<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"&gt;="</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lrel<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><CODE> </CODE>}<BR><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"REM"</CODE><CODE> </CODE><CODE>[</CODE><CODE>^</CODE><CODE> </CODE><CODE>'\n'</CODE><CODE>]*</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lrem<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"LET"</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Llet<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"PRINT"</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lprint<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"INPUT"</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Linput<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"IF"</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lif<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"THEN"</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lthen<CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"GOTO"</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lgoto<CODE> </CODE>}<BR><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"RUN"</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lcmd<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"LIST"</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lcmd<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>"END"</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lcmd<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[</CODE><CODE>'0'</CODE><CODE>-</CODE><CODE>'9'</CODE><CODE>]+</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lint<CODE> </CODE><TT>(</TT>int_of_string<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[</CODE><CODE>'A'</CODE><CODE>-</CODE><CODE>'z'</CODE><CODE>]+</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lident<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><CODE> </CODE>}<BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>'"'</CODE><CODE> </CODE><CODE>[</CODE><CODE>^</CODE><CODE> </CODE><CODE>'"'</CODE><CODE>]*</CODE><CODE> </CODE><CODE>'"'</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>Lstring<CODE> </CODE><TT>(</TT>string_chars<CODE> </CODE><TT>(</TT>Lexing.lexeme<CODE> </CODE>lexbuf<TT>)</TT><TT>)</TT><CODE> </CODE>}<BR>

</PRE>

<BR>
<BR>
Note that we isolated symbol <TT>=</TT>
which is used in both expressions and assignments.<BR>
<BR>
Only two of these regular expressions need further remarks. The first
concerns comment lines (<CODE>"REM" [^ '\n']*</CODE>). This rule
recognizes keyword <TT>REM</TT> followed by an arbitrary number of
characters other than <CODE>'\n'</CODE>. The second remark concerns character
strings (<CODE>'"' [^ '"']* '"'</CODE>) considered as sequences of
characters different from <CODE>"</CODE> and contained between two <CODE>"</CODE>.<BR>
<BR>
<A NAME="toc144"></A>
<H3> Compiling, Linking</H3>
<A NAME="@fonctions360"></A>
<A NAME="@fonctions361"></A>
The compilation of the lexer and parser must be carried out
in a definite order. This is due to the mutual dependency
between the declaration of lexemes. To compile our example, we must
enter the following sequence of commands:
<PRE>
ocamlc -c basic_types.mli
ocamlyacc basic_parser.mly
ocamllex basic_lexer.mll
ocamlc -c basic_parser.mli
ocamlc -c basic_lexer.ml
ocamlc -c basic_parser.ml
</PRE>Which will generate files <TT>basic_lexer.cmo</TT> and <TT>basic_parser.cmo</TT> which may be linked into an application.<BR>
<BR>
We now have at our disposal all the material needed to reimplement the
application. <BR>
<BR>
We suppress all types and all functions in paragraphs 
``lexical analysis'' (on page <A HREF="book-ora058.html#basic-lex0">??</A>) and
``parsing'' ( on page <A HREF="book-ora058.html#basic-synt0">??</A>) of our Basic
application; in function <TT>one_command</TT> (on page
<A HREF="book-ora058.html#fun-une-commande">??</A>), we replace expression


<PRE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>parse<CODE> </CODE><TT>(</TT>input_line<CODE> </CODE>stdin<TT>)</TT><CODE> </CODE><B>with</B><BR>

</PRE>

with


<PRE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>line<CODE> </CODE>lexer<CODE> </CODE><TT>(</TT>Lexing.from_string<CODE> </CODE><TT>(</TT><TT>(</TT>input_line<CODE> </CODE>stdin<TT>)</TT><CODE>^</CODE><CODE>"\n"</CODE><TT>)</TT><TT>)</TT><CODE> </CODE><B>with</B><CODE> </CODE><BR>

</PRE>

<BR>
<BR>
We need to remark that we must put back at the end of the line
the character <CODE>'\n'</CODE> which function <TT>input_line</TT> had filtered
out. This is necessary because the <CODE>'\n'</CODE> character indicates the
end of a command line (<TT>Leol</TT>).<BR>
<BR>
<BR>
<BR>

<BR>
<BR>
<HR>
<A HREF="book-ora106.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora108.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
